package com.minisoft.utils;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.zip.*;

public class JarSlimmer {

    public static void main(String[] args) throws IOException {
        String dependenciesFilePath = "C:\\Users\\31594\\IdeaProjects\\huafa-open-online-service\\lib.txt";
        File sourceDir = new File("C:\\Users\\31594\\IdeaProjects\\huafa-open-online-service\\Output\\2024-05-14");
        File targetDir = new File("E:\\huafa-open-online-service\\Output\\2024-05-14");
        if (!targetDir.exists()) {
            targetDir.mkdirs();
        }

        Set<String> dependenciesToRemove = readDependencies(dependenciesFilePath);
        processDirectory(sourceDir, targetDir, dependenciesToRemove);
    }

    private static Set<String> readDependencies(String filePath) throws IOException {
        Set<String> dependencies = new HashSet<>();
        try (BufferedReader reader = Files.newBufferedReader(Paths.get(filePath))) {
            String line;
            while ((line = reader.readLine()) != null) {
                dependencies.add(line.trim());
            }
        }
        return dependencies;
    }

    private static void processDirectory(File sourceDir, File targetDir, Set<String> dependenciesToRemove) throws IOException {
        File[] files = sourceDir.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile() && file.getName().endsWith(".jar")) {
                    String targetJarPath = Paths.get(targetDir.getAbsolutePath(), file.getName()).toString();
                    slimJar(file.getAbsolutePath(), targetJarPath, dependenciesToRemove);
                }
            }
        }
    }

    private static void slimJar(String sourceJarPath, String targetJarPath, Set<String> dependenciesToRemove) throws IOException {
        System.out.println("process " + sourceJarPath);
        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(sourceJarPath));
             ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetJarPath))) {

            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                ZipEntry finalEntry = entry;
                boolean toRemove = dependenciesToRemove.stream().anyMatch(dependency -> finalEntry.getName().endsWith(dependency));
                if (!toRemove) {
//                    System.out.println(entry);
                    ZipEntry newEntry = new ZipEntry(entry.getName());
                    newEntry.setMethod(entry.getMethod());
                    if (entry.getMethod() == ZipEntry.STORED) {
                        newEntry.setSize(entry.getSize());
                        newEntry.setCompressedSize(entry.getSize());
                        newEntry.setCrc(entry.getCrc());
                    }
                    zos.putNextEntry(newEntry);
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = zis.read(buffer)) > 0) {
                        zos.write(buffer, 0, length);
                    }
                    zos.closeEntry();
                }
                zis.closeEntry();
            }
        }
    }
}
